from JDjango.settings import CONFIG_PATH
from JDjango import validators
from JDjango.dialogs.MessageDialog.RichMessageDialog import RichMsgDialog
from JDjango.constant import *
from JDjango.validators import *
from JDjango.api import _tools as base_tools
import wx, os
import wx.lib.buttons as buttons
from typing import List

class ModelSerializerDialog(wx.Dialog):
    def __init__(self, parent, app_name: str, model_name: str, model_fields: List[str]):

        wx.Dialog.__init__(self, parent, id = wx.ID_ANY, title = f'序列化【{model_name}】', size=(555, 220), style=wx.DEFAULT_DIALOG_STYLE|wx.MAXIMIZE_BOX|wx.MINIMIZE_BOX|wx.RESIZE_BORDER)

        self.app_name = app_name # 如： 'apps.myapp' 存在多级的情况
        self.model_name = model_name
        self.model_fields = model_fields

        self._init_data()
        self._init_UI()
        self._init_listener()

    def _init_data(self):
        '''初始化数据包'''
        self.choices = None # 选择序列化的字段集

    def _init_UI(self):
        '''初始化界面布局'''
        self.panel = wx.Panel(self)
        self.panelSizer = wx.BoxSizer(wx.VERTICAL)
        self.panel.SetSizer(self.panelSizer)

        '''
            弹性网格布局
        '''
        self.flexGridSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
        self.panelSizer.Add(self.flexGridSizer, 1, wx.EXPAND | wx.ALL, 5)
        self.flexGridSizer.AddGrowableCol(1) # 第二列自适应大小

        self.inputName = wx.TextCtrl(self.panel, -1, '', validator=AlphaOnlyValidator())
        self.btnSave = buttons.GenButton(self.panel, -1, "保存")
        self.btnSave.SetBackgroundColour(CON_COLOR_MAIN)
        self.btnSave.SetForegroundColour(CON_COLOR_PURE_WHITE)

        self.btnSelectFields = buttons.GenButton(self.panel, -1, "选择序列化字段")
        self.btnSelectFields.SetBackgroundColour(CON_COLOR_MAIN)
        self.btnSelectFields.SetForegroundColour(CON_COLOR_PURE_WHITE)
        self.inputSelectFields = wx.TextCtrl(self.panel, -1, ', '.join(self.model_fields), style=wx.TE_READONLY)

        # 填充网格
        self.flexGridSizer.Add(wx.StaticText(self.panel, -1, label='序列化模型命名：'), 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.flexGridSizer.Add(self.inputName, 0, wx.EXPAND)
        self.flexGridSizer.Add(self.btnSave, 0, wx.EXPAND)

        self.flexGridSizer.Add(wx.StaticText(self.panel, -1, label='默认序列化所有字段'), 0, wx.ALIGN_RIGHT|wx.ALIGN_CENTER_VERTICAL)
        self.flexGridSizer.Add(self.inputSelectFields, 0, wx.EXPAND)
        self.flexGridSizer.Add(self.btnSelectFields, 0, wx.EXPAND)

    def _init_listener(self):
        '''初始化注册监听'''
        self.Bind(wx.EVT_BUTTON, self.onBtnSelectFields, self.btnSelectFields)
        self.Bind(wx.EVT_BUTTON, self.onBtnSave, self.btnSave)

    def onBtnSelectFields(self, evt):
        '''选择需要序列化的选项'''
        self.choices = RichMsgDialog.showMultiChoiceDialog(
            self
            , "请从以下的字段中选择："
            , "选择要序列化字段"
            , self.model_fields
        )
        self.inputSelectFields.SetValue(', '.join(self.choices))

    def onBtnSave(self, evt):
        '''保存序列化模型'''
        serializer_name = self.inputName.GetValue().strip()

        if not serializer_name:
            RichMsgDialog.showOkMsgDialog(self, "请先命名序列化模型！", "错误")
            return

        if not self.choices:
            RichMsgDialog.showOkMsgDialog(self, "请选择要序列化的字段集！不允许为空！", "错误")
            return

        fields = ", ".join([f"'{_}'" for _ in self.choices])

        template = f"""
class {serializer_name}Serializer(serializers.ModelSerializer):
    class Meta:
        model = {self.model_name}
        fields = ({fields})
"""
        # 写入序列化文件【serializers.py】，文件应该直属于应该程序根路径。
        # 如果没有此文件，则程序会新建文件，然后插入相关代码

        '''
            根据多级的应用程序名，锁定应用程序根路径
        '''
        base_app_path = os.path.join(base_tools.get_configs(CONFIG_PATH)["dirname"], *self.app_name.split("."))

        if not os.path.exists(base_app_path): # 正常不会触发（触发就是异常）
            RichMsgDialog.showOkMsgDialog(self, "应用程序根路径不存在，程序异常！！！", "错误")
            return

        ser_path = os.path.join(base_app_path, 'serializers.py')
        '''
            没有则新增
        '''
        if not os.path.exists(ser_path):
            base_tools.new_file(ser_path, content=[
                "from .models import *\n",
                "from rest_framework import serializers\n\n"
            ])

        """
            确保存在的情况下，插入新的序列化模板
        """
        base_tools.append_file(ser_path, template.split('\n'), join_str='\n')
